/*
 * Copyright 2008 Nathan C Jones
 * 
 * This file is part of Fivehundred.
 * 
 * Fivehundred is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * Fivehundred is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * Fivehundred. If not, see <http://www.gnu.org/licenses/>. 
 */

package com.googlecode.fivehundred.ui.simple;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JComponent;

import com.googlecode.fivehundred.model.Card;
import com.googlecode.fivehundred.model.CardCollection;
import com.googlecode.fivehundred.model.CardCollectionListener;
import com.googlecode.fivehundred.model.CardPile;

/**
 * The area of a game board where cards get played and discarded.
 * 
 * @author Nathan C Jones
 */
public class DiscardPanel extends JComponent implements CardCollectionListener {

	private static final long serialVersionUID = 1L;

	private CardPile cardPile;

	private Position discardPosition;

	private Map<Card, JCard> cards = new HashMap<Card, JCard>();

	/**
	 * Create a new discard area.
	 * 
	 * @param cardPile the discard pile to visualise.
	 * @throws IllegalArgumentException if the card pile is not empty.
	 */
	public DiscardPanel(final CardPile cardPile) {
		if (cardPile.size() > 0) {
			throw new IllegalArgumentException("Card pile was not empty when creating new discard area.");
		}
		this.cardPile = cardPile;
		cardPile.addCardCollectionListener(this);
		init();
	}

	private void init() {
		setPreferredSize(new Dimension(640, 480));
	}

	// TODO extract these methods (and those in JHand) to a superclass
	@Override
	public void cardAdded(Card card, CardCollection collection) {
		addCard(card);
	}

	@Override
	public void cardRemoved(Card card, CardCollection collection) {
		removeCard(card);
	}

	private void addCard(Card card) {
		final JCard jCard = new JCard(card);
		cards.put(card, jCard);
		add(jCard, discardPosition.getConstraint());
		discardPosition = discardPosition.getNextPosition();
		validate();
	}

	private void removeCard(Card card) {
		final JCard jCard = cards.get(card);
		if (card != null) {
			remove(jCard);
			cards.remove(card);
			validate();
		}
	}

	private static class Position {
		private Position next;
		private final Object constraint;

		public Position(Object constraint) {
			this.constraint = constraint;
		}

		public Position getNextPosition() {
			return next;
		}

		public Object getConstraint() {
			return constraint;
		}
	}

	// TODO might not need these enumerations in this class - game or player
	// might be better instead (discard area could be constructed with reference
	// to game controller, then use controller.getCurrentPlayerPosition)
	private static Position NORTH = new Position(BorderLayout.NORTH);
	private static Position EAST = new Position(BorderLayout.EAST);
	private static Position SOUTH = new Position(BorderLayout.SOUTH);
	private static Position WEST = new Position(BorderLayout.WEST);
	static {
		NORTH.next = EAST;
		EAST.next = SOUTH;
		SOUTH.next = WEST;
		WEST.next = NORTH;
	}
}
